package negocio.bd;

import base.Estado;
import base.Servicio;
import base.Tarea;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.GregorianCalendar;
import utiles.ConexionBD;
import utiles.ConversorFecha;
import utiles.Logger;

/**
 *
 * @author Efren
 */
public class BDTareas {
    public static final String idTarea = "idTarea";
    public static final String estado = "estado";
    public static final String prioridad = "prioridad";
    public static final String idEmpleado = "idEmpleado";
    public static final int buscarPorEstado = 1;
    public static final int buscarPorPrioridad = 2;
    public static final int buscarPorId = 2;
    public static final int ASC = 1;
    public static final int DESC = 2;
    
     public static int consultar(String query){
        java.sql.Connection db = new ConexionBD().getConnection();
        try {
            java.sql.Statement select =  db.createStatement();
            java.sql.ResultSet res = select.executeQuery(query);
            if (res.next()){
                return res.getInt(1);
            }
        } catch (SQLException ex){
            Logger.printError(ex.getMessage());
        }return -1;
    }
    public static Tarea[]  buscar(int campoBusqueda, String busqueda, int orden, boolean exacta){
        java.sql.Connection db = new ConexionBD().getConnection();
        ArrayList<Tarea> tareas = new  ArrayList<>(0);
        String query = "SELECT * FROM `gestionTienda`.`Tarea` ";
        if  (campoBusqueda == buscarPorEstado){
                query += "WHERE " + estado + " like '" + busqueda +"%' ORDER BY " + estado;
        } else {
                if (campoBusqueda == buscarPorPrioridad){
                    query += "WHERE " + prioridad + " like '" + busqueda + "%' ORDER BY " + prioridad;
                } else{
                    query += "WHERE " + idTarea + " like '" + busqueda + "%' ORDER BY " + idTarea;
                }
        }
        //Si la busqueda a de ser exacta quitar like y % de la consulta
        if (exacta){
            query = query.replaceAll("like", "=");
            query = query.replace("%", "");
        }
        if (orden == DESC){
            query += " DESC";
        } else {
            query += " ASC";
        }
        try {
            java.sql.Statement statement = db.createStatement();
            java.sql.ResultSet res = statement.executeQuery(query);
            while (res.next()){
                Tarea temp = new Tarea();
                temp.setIdTarea(res.getLong(idTarea));
                temp.setEstado(Estado.valueOf(res.getString(estado)));
                temp.setPrioridad(res.getInt(prioridad));
                temp.setServiciosPrestados(BDServicios.obtenerPrestados(temp.getIdTarea()));
                temp.setIdEmpleado(obtenerEmpleadosParticipantes(temp.getIdTarea()));
                temp.setDNICliente(BDPeticiones.obtener(temp.getIdTarea()).getCliente().getDni());
                tareas.add(temp);
            }
            return tareas.toArray(new Tarea[0]);
        } catch (SQLException ex){
            Logger.printError(ex.getMessage());
        }
        return null;
    }
    public static Tarea[] buscarPorDNI(String dni){
        java.sql.Connection db = new ConexionBD().getConnection();
        ArrayList<Tarea> tareas = new  ArrayList<>(0);
        try {
            String query = "SELECT * FROM `gestionTienda`.`Tarea` INNER JOIN `gestionTienda`.`Peticiones` ON Tarea.idTarea = Peticiones.idPeticion WHERE dni like '" + dni+ "%' ";
            java.sql.Statement statement = db.createStatement();
            java.sql.ResultSet res = statement.executeQuery(query);
            while (res.next()){
                Tarea temp = new Tarea();
                temp.setIdTarea(res.getLong(idTarea));
                temp.setEstado(Estado.valueOf(res.getString(estado)));
                temp.setPrioridad(res.getInt(prioridad));
                temp.setServiciosPrestados(BDServicios.obtenerPrestados(temp.getIdTarea()));
                temp.setIdEmpleado(obtenerEmpleadosParticipantes(temp.getIdTarea()));
                temp.setDNICliente(BDPeticiones.obtener(temp.getIdTarea()).getCliente().getDni());
                tareas.add(temp);
            }
            return tareas.toArray(new Tarea[0]);
        } catch (SQLException ex){
            Logger.printError(ex.getMessage());
        }
        return null;
    }
    public static Tarea[] buscarTareasFinalizadas(){
        java.sql.Connection db = new ConexionBD().getConnection();
        ArrayList<Tarea> tareas = new  ArrayList<>(0);
        try {
            String query = "SELECT * FROM `gestionTienda`.`Tarea` WHERE estado = 'FINALIZADO' AND fechaFinalizada > DATE_SUB(CURDATE(),INTERVAL 1 MONTH)";
            java.sql.Statement statement = db.createStatement();
            java.sql.ResultSet res = statement.executeQuery(query);
            while (res.next()){
                Tarea temp = new Tarea();
                temp.setIdTarea(res.getLong(idTarea));
                temp.setEstado(Estado.valueOf(res.getString(estado)));
                temp.setPrioridad(res.getInt(prioridad));
                temp.setFechaFinalizado(ConversorFecha.obtenerFecha(res.getDate("fechaFinalizada")));
                temp.setServiciosPrestados(BDServicios.obtenerPrestados(temp.getIdTarea()));
                temp.setIdEmpleado(obtenerEmpleadosParticipantes(temp.getIdTarea()));
                temp.setDNICliente(BDPeticiones.obtener(temp.getIdTarea()).getCliente().getDni());
                tareas.add(temp);
            }
            return tareas.toArray(new Tarea[0]);
        } catch (SQLException ex){
            Logger.printError(ex.getMessage());
        }
        return null;
    }
    public static GregorianCalendar[] buscarFechasTareasFinalizadas(){
        java.sql.Connection db = new ConexionBD().getConnection();
        ArrayList<GregorianCalendar> fechas = new  ArrayList<>(0);
        try {
            String query = "SELECT fechaFinalizada FROM `gestionTienda`.`Tarea` WHERE estado = 'FINALIZADO' AND fechaFinalizada > DATE_SUB(CURDATE(),INTERVAL 1 MONTH) GROUP BY fechaFinalizada";
            java.sql.Statement statement = db.createStatement();
            java.sql.ResultSet res = statement.executeQuery(query);
            while (res.next()){
                fechas.add(ConversorFecha.obtenerFecha(res.getDate("fechaFinalizada")));
            }
            return fechas.toArray(new GregorianCalendar[0]);
        } catch (SQLException ex){
            Logger.printError(ex.getMessage());
        }
        return null;
    }
    public static Tarea obtener(long idTarea){
        java.sql.Connection db = new ConexionBD().getConnection();
        try {
            java.sql.Statement select = db.createStatement();
            java.sql.ResultSet res = select.executeQuery("SELECT * FROM `gestionTienda`.`Tarea` WHERE " + BDTareas.idTarea + " = " + idTarea);
            while (res.next()){
                Tarea temp = new Tarea();
                temp.setIdTarea(res.getLong(BDTareas.idTarea));
                temp.setEstado(Estado.valueOf(res.getString(estado)));
                temp.setPrioridad(res.getInt(prioridad));
                temp.setServiciosPrestados(BDServicios.obtenerPrestados(temp.getIdTarea()));
                temp.setIdEmpleado(obtenerEmpleadosParticipantes(temp.getIdTarea()));
                temp.setDNICliente(BDPeticiones.obtener(temp.getIdTarea()).getCliente().getDni());
                return temp;
            }
        }catch (SQLException ex){
            Logger.printError(ex.getMessage());
        }return null;
    }
     public static boolean existe(long idTarea){
        java.sql.Connection db = new ConexionBD().getConnection();
        try {
            java.sql.Statement select = db.createStatement();
            java.sql.ResultSet res = select.executeQuery("SELECT * FROM `gestionTienda`.`Tarea` WHERE " + BDTareas.idTarea + " = " + idTarea);
            if (res.next()){
                return true;
            }
        } catch (SQLException ex){
            Logger.printError(ex.getMessage());
        }return false;
    }
    public static Tarea[] obtenerTodos(){
        java.sql.Connection db = new ConexionBD().getConnection();
        ArrayList<Tarea> recogidas = new  ArrayList<>(0);
        String query = "SELECT * FROM `gestionTienda`.`Tarea`";
        try {
            java.sql.Statement statement = db.createStatement();
            java.sql.ResultSet res = statement.executeQuery(query);
            while (res.next()){
                Tarea temp = new Tarea();
                temp.setIdTarea(res.getLong(idTarea));
                temp.setEstado(Estado.valueOf(res.getString(estado)));
                temp.setPrioridad(res.getInt(prioridad));
                temp.setServiciosPrestados(BDServicios.obtenerPrestados(temp.getIdTarea()));
                obtenerEmpleadosParticipantes(temp.getIdTarea());
                temp.setDNICliente(BDPeticiones.obtener(temp.getIdTarea()).getCliente().getDni());
                recogidas.add(temp);
            }
            return recogidas.toArray(new Tarea[0]);
        } catch (SQLException ex){
            Logger.printError(ex.getMessage());
        }
        return null;
    }
    public static boolean insertar(Tarea tarea){
        if (!existe(tarea.getIdTarea())){
            java.sql.Connection db = new ConexionBD().getConnection();
            try {
                java.sql.PreparedStatement insert = db.prepareStatement("INSERT INTO `gestionTienda`.`Tarea` (`idTarea` ,`estado` ,`prioridad` ,`fechaInicio`) VALUES (?,?,?,?)");
                insert.setLong(1, tarea.getIdTarea());
                insert.setString(2, tarea.getEstado().name());
                insert.setInt(3, tarea.getPrioridad());
                insert.setString(4, ConversorFecha.formatearSoloFecha(new GregorianCalendar()));
                insert.executeUpdate();
                insertarEmpleadosParticipantes(tarea);
                insertarPrestados(tarea);
                return true;
            } catch (SQLException ex){
                Logger.printError(ex.getMessage());
            }
        }return false;
    }
    public static boolean actualizar(Tarea tarea){
        if (existe(tarea.getIdTarea())){
            java.sql.Connection db = new ConexionBD().getConnection();
            try {
                java.sql.PreparedStatement update = db.prepareStatement("UPDATE `gestionTienda`.`Tarea` SET " + estado + " = ? ," + prioridad +" = ?, fechaFinalizada = ? WHERE " + BDTareas.idTarea + " = ?");
                    update.setString(1, tarea.getEstado().name());
                    update.setInt(2, tarea.getPrioridad());
                    update.setString(3, ConversorFecha.formatearSoloFecha(new GregorianCalendar()));
                    update.setLong(4, tarea.getIdTarea());
                    update.executeUpdate();
                    actualizarEmpleadosParticipantes(tarea);
                    actualizarPrestados(tarea);
                if (update.executeUpdate()==1){
                    return true;
                }
            } catch (SQLException ex){
                Logger.printError(ex.getMessage());
            }
        }return false;
    }
    public static boolean insertarPrestados(Tarea tarea) {
        java.sql.Connection db = new ConexionBD().getConnection();
        try {
            java.sql.PreparedStatement insert = db.prepareStatement("INSERT INTO `gestionTienda`.`Servicios_prestados_Tarea` VALUES (?,?,?)");
            for (Servicio temp : tarea.getServiciosPrestados()){
                insert.setInt(1, temp.getIdServicio());
                insert.setLong(2, tarea.getIdTarea());
                insert.setInt(3, temp.getUnidades());
                insert.executeUpdate();
            }
            return true;
        } catch (SQLException ex){
            Logger.printError(ex.getMessage());
        }return false;
    }

    public static void actualizarPrestados(Tarea tarea) {
        java.sql.Connection db = new ConexionBD().getConnection();
        Servicio[] estimadosBD = BDServicios.obtenerPrestados(tarea.getIdTarea());
        try {
            if ( estimadosBD == null){
                //Si no hay servicios añadidos realizamos insercion.
                insertarPrestados(tarea);
            } else {
                java.sql.Statement delete = db.createStatement();
                delete.executeUpdate("DELETE FROM `gestionTienda`.`Servicios_prestados_Tarea` WHERE idTarea = " + tarea.getIdTarea());
                insertarPrestados(tarea);
            }
        } catch (SQLException ex){
            Logger.printError(ex.getMessage());
        }
    }
    public static void borrar(long idTarea) {
        java.sql.Connection db = new ConexionBD().getConnection();
        try {
            java.sql.Statement delete = db.createStatement();
            delete.executeUpdate("DELETE FROM `gestionTienda`.`Servicios_prestados_Tarea` WHERE idTarea = " + idTarea);
        } catch (SQLException ex){
            Logger.printError(ex.getMessage());
        }
    }
     private static boolean insertarEmpleadosParticipantes(Tarea tarea) {
        java.sql.Connection db = new ConexionBD().getConnection();
        try {
            java.sql.PreparedStatement insert = db.prepareStatement("INSERT INTO `gestionTienda`.`Participan` VALUES (?,?)");
            for (int temp : tarea.getIdEmpleado()){
                insert.setInt(1, temp);
                insert.setLong(2, tarea.getIdTarea());
                insert.executeUpdate();
            }
            return true;
        } catch (SQLException ex){
            Logger.printError(ex.getMessage());
        }return false;
    }

    private static void actualizarEmpleadosParticipantes(Tarea tarea) {
        java.sql.Connection db = new ConexionBD().getConnection();
        int[] participanBD = obtenerEmpleadosParticipantes(tarea.getIdTarea());
        try {
            if ( participanBD == null){
                //Si no hay servicios añadidos realizamos insercion.
                insertarEmpleadosParticipantes(tarea);
            } else {
                java.sql.Statement delete = db.createStatement();
                delete.executeUpdate("DELETE FROM `gestionTienda`.`Participan` WHERE idTarea = " + tarea.getIdTarea());
                insertarEmpleadosParticipantes(tarea);
            }
        } catch (SQLException ex){
            Logger.printError(ex.getMessage());
        }
    }

    private static int[] obtenerEmpleadosParticipantes(long idTarea) {
        java.sql.Connection db = new ConexionBD().getConnection();
        ArrayList<Integer> ids = new ArrayList<>(0);
        try {
            java.sql.Statement select = db.createStatement();
            java.sql.ResultSet res = select.executeQuery("SELECT idEmpleado FROM `gestionTienda`. `Participan` WHERE idTarea =" + idTarea );
            while (res.next()){
                ids.add(res.getInt("idEmpleado"));
            }
            int[] result = new int[ids.size()];
            for (int i = 0; i < result.length; i++){
                result[i] = ids.get(i);
            }
            return result;
        } catch (SQLException ex){
            Logger.printError(ex.getMessage());
        } return new int[0];
    }
    
    public static Tarea[] obtenerTareasTecnico(int idTecnico){
        java.sql.Connection db = new ConexionBD().getConnection();
        ArrayList<Tarea> tareas = new ArrayList<>(0);
        try {
            java.sql.Statement select = db.createStatement();
            java.sql.ResultSet res = select.executeQuery("SELECT * FROM `gestionTienda`.`Tarea` INNER JOIN `gestionTienda`.`Participan` ON Participan.idTarea = Tarea.idTarea WHERE " + BDTareas.idEmpleado + " = " + idTecnico+ " AND estado = 'PENDIENTE'");
            while (res.next()){
                Tarea temp = new Tarea();
                temp.setIdTarea(res.getLong(BDTareas.idTarea));
                temp.setEstado(Estado.valueOf(res.getString(estado)));
                temp.setPrioridad(res.getInt(prioridad));
                temp.setServiciosPrestados(BDServicios.obtenerPrestados(temp.getIdTarea()));
                temp.setIdEmpleado(obtenerEmpleadosParticipantes(temp.getIdTarea()));
                temp.setDNICliente(BDPeticiones.obtener(temp.getIdTarea()).getCliente().getDni());
                tareas.add(temp);
            }
            return tareas.toArray(new Tarea[0]);
        }catch (SQLException ex){
            Logger.printError(ex.getMessage());
        }return null;
    }
    public static int obtenerNumeroTareasTecnico(int idTecnico){
        java.sql.Connection db = new ConexionBD().getConnection();
       int cont = 0;
        try {
            java.sql.Statement select = db.createStatement();
            java.sql.ResultSet res = select.executeQuery("SELECT * FROM `gestionTienda`.`Tarea` INNER JOIN `gestionTienda`.`Participan` ON Participan.idTarea = Tarea.idTarea WHERE " + BDTareas.idEmpleado + " = " + idTecnico+ " AND estado = 'PENDIENTE'");
            while (res.next()){
                cont++;
            }
            return cont;
        }catch (SQLException ex){
            Logger.printError(ex.getMessage());
        }return -1;
    }
}
